package com.ltcode.auth.infrastructure.service;

import com.ltcode.auth.domain.service.PasswordService;
import com.ltcode.common.base.exception.BizException;
import com.ltcode.common.base.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.security.SecureRandom;
import java.util.regex.Pattern;

/**
 * 密码服务实现
 * 
 * @author ltcode
 * @since 2024-01-01
 */
@Slf4j
@Service
public class PasswordServiceImpl implements PasswordService {

    private static final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*";
    private static final SecureRandom RANDOM = new SecureRandom();

    // 密码强度正则表达式
    private static final Pattern WEAK_PATTERN = Pattern.compile("^[a-zA-Z]+$|^[0-9]+$");
    private static final Pattern MEDIUM_PATTERN = Pattern.compile("^(?=.*[a-zA-Z])(?=.*[0-9]).{6,}$");
    private static final Pattern STRONG_PATTERN = Pattern.compile("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*]).{8,}$");

    @Override
    public String encryptPassword(String rawPassword) {
        try {
            return SecurityUtils.encryptPassword(rawPassword);
        } catch (Exception e) {
            log.error("密码加密失败", e);
            throw new BizException("密码加密失败", e);
        }
    }

    @Override
    public boolean matches(String rawPassword, String encodedPassword) {
        try {
            return SecurityUtils.matchesPassword(rawPassword, encodedPassword);
        } catch (Exception e) {
            log.error("密码验证失败", e);
            return false;
        }
    }

    @Override
    public String generateRandomPassword(int length) {
        if (length < 6) {
            length = 6;
        }
        if (length > 50) {
            length = 50;
        }

        StringBuilder password = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            password.append(CHARACTERS.charAt(RANDOM.nextInt(CHARACTERS.length())));
        }

        return password.toString();
    }

    @Override
    public boolean validatePasswordStrength(String password) {
        if (password == null || password.length() < 6) {
            return false;
        }

        // 至少包含字母和数字
        return MEDIUM_PATTERN.matcher(password).matches();
    }

    @Override
    public String getPasswordStrengthDescription(String password) {
        if (password == null || password.length() < 6) {
            return "密码长度至少6位";
        }

        if (STRONG_PATTERN.matcher(password).matches()) {
            return "强密码";
        } else if (MEDIUM_PATTERN.matcher(password).matches()) {
            return "中等密码";
        } else if (WEAK_PATTERN.matcher(password).matches()) {
            return "弱密码";
        } else {
            return "密码强度未知";
        }
    }
}
